package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VisitorsVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MovementService {

    @Autowired
    private OssTemplate ossTemplate;
    @DubboReference
    private MovementApi movementApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private VisitorsApi visitorsApi;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private MqMessageService mqMessageService;
    /**
     * 发布动态
     * @param movement
     * @param imageContent
     */
    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        //1.判断发布的内容是否存在
        if (StringUtils.isEmpty(movement.getTextContent())){
            throw new BusinessException(ErrorResult.contentError());
        }
        //2.获取当前登录用户的id
        Long userId = UserHolder.getId();
        //3.将文件内容上传到阿里oss，获取请求地址
        List<String> medias=new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(upload);
        }
        //4.将数据封装到Movement对象
        movement.setUserId(userId);
        movement.setMedias(medias);
        //5.调用API完成发布动态
        String publishId = movementApi.publish(movement);
        mqMessageService.sendAudiService(publishId);
    }
    //查询个人动态
    public PageResult findByUserId(Long userId, Integer page, Integer pagesize) {
        //1、根据用户id，调用API查询个人动态内容（PageResult  -- Movement）
        PageResult pr=movementApi.findByUserId(userId,page,pagesize);
        //2、获取PageResult中的item列表对象
        List<Movement> items = (List<Movement>) pr.getItems();
        //3、非空判断
        if (items==null){
            return pr;
        }
        UserInfo userInfo = userInfoApi.findById(userId);
        //4、循环数据列表
        List<MovementsVo> list=new ArrayList<>();
        for (Movement item : items) {
            //5、一个Movement构建一个Vo对象
            MovementsVo vo = MovementsVo.init(userInfo, item);
            list.add(vo);
        }

        //6、构建返回值
        pr.setItems(list);
        return pr;
    }
    //查询好友动态
    public PageResult findFriendMovements(Integer page, Integer pagesize) {
        //1、获取当前用户id
        Long userId = UserHolder.getId();
        //2、查询数据列表
        List<Movement> list=movementApi.findFriendMovements(page,pagesize,userId);
        return getPageResult(page,pagesize,list);
    }

    public PageResult getPageResult(Integer page, Integer pagesize,List<Movement> list) {
            //3、非空判断
            if (CollUtil.isEmpty(list)) {
                return new PageResult();
            }
            //4、获取好友用户id
            List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
            //5、循环数据列表,根据用户的id列表获取用户详情
            Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
            List<MovementsVo> vos = new ArrayList<>();
            for (Movement movement : list) {
                //5.1一个Movement构建一个Vo对象
                UserInfo userInfo = map.get(movement.getUserId());
                if (userInfo != null) {
                    MovementsVo vo = MovementsVo.init(userInfo, movement);
                    String key= Constants.MOVEMENTS_INTERACT_KEY+movement.getId().toHexString();
                    String hashKey=Constants.MOVEMENT_LIKE_HASHKEY+UserHolder.getId();
                    if(redisTemplate.opsForHash().hasKey(key,hashKey)) {
                        vo.setHasLiked(1);
                    }
                    String lovehashKey=Constants.MOVEMENT_LOVE_HASHKEY+UserHolder.getId();
                    if(redisTemplate.opsForHash().hasKey(key,lovehashKey)) {
                        vo.setHasLoved(1);
                    }
                    vos.add(vo);
                }
            }

                //6、构建返回值
                return new PageResult(page, pagesize, 0, vos);
    }

    //查询推荐动态
    public PageResult findrecommendMovements(Integer page, Integer pagesize) {
        //1.从redis中获取推荐数据
        String redisKe= Constants.MOVEMENTS_RECOMMEND+UserHolder.getId();
        String redisValue = redisTemplate.opsForValue().get(redisKe);
        //2.判断推荐数据是否存在
        List<Movement> list= Collections.EMPTY_LIST;
        if (StringUtils.isEmpty(redisValue)) {
            //3.如果不存在，调用API随机构造10条动态数据
            list=movementApi.randomMovements(pagesize);
        }else {
            //4.如果存在，处理pid数据
            String[] split = redisValue.split(",");
            //判断当前页的起始页是否小于数组
            if ((page-1)*pagesize < split.length){
                List<Long> pids = Arrays.stream(split).skip((page - 1) * pagesize).limit(pagesize)
                        .map(e ->Long.valueOf(e))
                        .collect(Collectors.toList());
                //5.调用Api根据pid数组查询动态数据
                list=movementApi.randomMovementsByPids(pids);
            }
        }
        //6.调用公共方法构造返回值
        return getPageResult(page,pagesize,list);
    }
    //查询单条动态
    public MovementsVo findById(String movementId) {
        mqMessageService.sendLogService(UserHolder.getId(),"0202","movement",movementId);
        //1.调用api根据id查询动态详情
        Movement movement=movementApi.findById(movementId);
        //2.转化vo对象
        if (movement != null){
            UserInfo userInfo = userInfoApi.findById(movement.getUserId());
            return MovementsVo.init(userInfo,movement);
        }else {
            return null;
        }
    }
    //首页-访客列表
    public List<VisitorsVo> queryVisitorsList() {
        //1、查询访问时间
        String key=Constants.VISITORS_USER;
        String hashkey=String.valueOf(UserHolder.getId());
        String value = (String) redisTemplate.opsForHash().get(key, hashkey);
        Long date=StringUtils.isEmpty(value) ? null:Long.valueOf(value);
        // 注意,此处从redis 中查询的时间 是 点击访客列表详情时才存储的,课堂未实现,属于作业部分
        //2、调用API查询数据列表 List<Visitors>
        List<Visitors> list=visitorsApi.queryMyVisitors(date,UserHolder.getId());
        if (CollUtil.isEmpty(list)){
            return new ArrayList<>();
        }
        //3、提取用户的id
        List<Long> userIds = CollUtil.getFieldValues(list, "visitorUserId", Long.class);
        //4、查看用户详情
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
        //5、构造返回
        List<VisitorsVo> vos=new ArrayList<>();
        for (Visitors visitors : list) {
            UserInfo userInfo = map.get(visitors.getVisitorUserId());
            if (userInfo!=null){
                VisitorsVo vo = VisitorsVo.init(userInfo, visitors);
                vos.add(vo);
            }
        }
        return vos;
    }
}
